package filesearcher;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import jxl.write.WriteException;
/**
 *
 * @author Misiacik
 */
public class SearcherFrame extends JFrame {
    
    private static JPanel buttonPanel;
    private static JPanel writeToFilePanel;
    private static JPanel rootsListPanel;
    private static List<String> listOfDirectories = new ArrayList<String>();
    private static List<String> listOfNonDir = new ArrayList<String>();
    private static JLabel label;
    private static JLabel rootsListLabel;

    private Timer cancelMonitor;
    private ProgressMonitor progressDialog;
    WritingToFile writingActivity;

    private WriteExcel excelFile;

    public SearcherFrame(){
        label = new JLabel("No Directory Selected");
        rootsListLabel = new JLabel("Available Disks: " + FileListing.getListOfRoots().toString());

        Toolkit kit = Toolkit.getDefaultToolkit();
        Dimension screenSize = kit.getScreenSize();
        setSize(screenSize.width/2, screenSize.height/2);

        setLocationByPlatform(true);

        setTitle("FileSearcher");

        Action addDirectory = new AddDirectoryAction();
        Action removeDirectory = new RemoveDirectoryAction();
        Action writeToFile = new WriteToFileAction();

        buttonPanel = new JPanel();
        writeToFilePanel = new JPanel();
        rootsListPanel = new JPanel();
        buttonPanel.add(new JButton(addDirectory));
        buttonPanel.add(label);
        buttonPanel.add(new JButton(removeDirectory));
        writeToFilePanel.add(new JButton(writeToFile));
        rootsListPanel.add(rootsListLabel);

        this.add(buttonPanel, BorderLayout.NORTH);
        this.add(writeToFilePanel, BorderLayout.SOUTH);
        this.add(rootsListPanel, BorderLayout.CENTER);

    }

    public void revalidate(){
        rootsListLabel.setText("Available Disks: " + FileListing.getListOfRoots().toString());
    }

    public class WriteToFileAction extends AbstractAction{

        public WriteToFileAction() {
            putValue(Action.NAME, "Write To File");
            putValue(Action.SHORT_DESCRIPTION, "Write List of Files to the Excel File");
        }

        public void actionPerformed(ActionEvent e) {
            //final int MAX = 1000;
            revalidate();
            if(listOfDirectories.isEmpty()){
                JOptionPane.showMessageDialog(null, "No Directories Selected!", "Message", 1);
                return;
            }

            JFileChooser chooser = new JFileChooser();
            FileNameExtensionFilter filter = new FileNameExtensionFilter("Excel files", "xls");
            chooser.setFileFilter(filter);
            chooser.setCurrentDirectory(new File("c:/temp"));
            //chooser.setSelectedFile(new File("c:/temp/list.xls"));
            chooser.showSaveDialog(null);
            File selectedFile = chooser.getSelectedFile();

            if(selectedFile == null || selectedFile.getName().equals(""))
                return;

            String inputFile = selectedFile.getPath();
            if(!inputFile.endsWith(".xls"))
                inputFile = inputFile + ".xls";
            int answer;
            boolean exists = (new File(inputFile)).exists();
            if(exists)
                answer = JOptionPane.showConfirmDialog(null, "File " + inputFile + " already exist. Data will be added to this file. Continue?", "Message", JOptionPane.YES_NO_OPTION);
            else
                answer = JOptionPane.showConfirmDialog(null, "File " + inputFile + " doesn't exist. Do you want to create this file?", "Message", JOptionPane.YES_NO_OPTION);

            if (answer != 0)    // if answer in not YES return
                return;

            excelFile = new WriteExcel();
            excelFile.setOutputFile(inputFile);

            final int MAX = 100;
            // start writingActivity
            writingActivity = new WritingToFile();
            writingActivity.execute();

            cancelMonitor = new Timer(500, new ActionListener() {
                public void actionPerformed(ActionEvent event) {
                    if (progressDialog.isCanceled()){
                        writingActivity.cancel(true);
                        JOptionPane.showMessageDialog(null, "Writing to file was canceled by the user", "Message", 1);
                        progressDialog.close();
                    }
                    else if (writingActivity.isDone()){
                        progressDialog.close();
                    }
                    else {
                        progressDialog.setProgress(writingActivity.getProgress());
                        //progressDialog.setNote("Operation is " + writingActivity.getProgress() + "% complete");
                        progressDialog.setNote("Scanning " + writingActivity.getScannedFile());
                    }
                }
            });

            // launch progress dialog
            progressDialog = new ProgressMonitor(SearcherFrame.this, "Scanning in progress...", "Initializing . . .", 0, MAX);
            cancelMonitor.start();
        }
    }

    public class WritingToFile extends SwingWorker<Void, Integer> {

        private String scannedFile;

        protected Void doInBackground() throws Exception {
            try {
                excelFile.write(listOfDirectories, writingActivity);
            } catch (IllegalArgumentException ex) {
                JOptionPane.showMessageDialog(null, "Destination File is Open! Please Close the File and Try It Again!", "Message", 1);
                return null;
            } catch (IOException ex) {
                JOptionPane.showMessageDialog(null, "Problem With Excel File!", "Message", 1);
                return null;
            } catch (WriteException ex) {
                JOptionPane.showMessageDialog(null, "Problem With Writing Into Excel File!", "Message", 1);
                return null;
            }
            setProgress(100);
            JOptionPane.showMessageDialog(null, "Names of files from " + listOfDirectories.toString() + " has been written to the file", "Message", 1);

            if(listOfDirectories.isEmpty())
                label.setText("No Directory Selected");
            else
                label.setText("Selected Directories : " + listOfDirectories.toString());

            revalidate();
            return null;
        }

        public void setWriringProgress(int newProgress, File file) {
            scannedFile = file.getPath();
            if (newProgress < 100 && newProgress >= 0){
                setProgress(newProgress);
            }
        }

        public String getScannedFile() {
            return scannedFile;
        }

    }

    public class AddDirectoryAction extends AbstractAction{

        public AddDirectoryAction() {
            putValue(Action.NAME, "Add Disk/Directory");
            putValue(Action.SHORT_DESCRIPTION, "Add Disk/Directory to the List");
        }

        public void actionPerformed(ActionEvent e) {
            revalidate();
            String list = JOptionPane.showInputDialog(null, "Input names of drives/directories and separe them with coma (\",\"):", "Add Directory", 1);
            if(list == null || list.isEmpty())
                return;
            String[] directories = list.split(",");
            for(String directory : directories){
                directory = directory.trim();
                if(!directory.isEmpty()){
                    if(directory.length() == 1 || (directory.length() == 2 && directory.endsWith(":"))){
                        directory = directory.charAt(0) + ":/";
                    }
                    if(!listOfDirectories.contains(directory)){
                        boolean exists = (new File(directory)).exists();
                        if(exists)
                            listOfDirectories.add(directory);
                        else
                            listOfNonDir.add(directory);
                    }
                }
            }
            if(!listOfNonDir.isEmpty()){
                JOptionPane.showMessageDialog(null, listOfNonDir.toString()+" doesn't exist! Select from "+FileListing.getListOfRoots().toString(), "Message", 1);
                listOfNonDir.removeAll(listOfNonDir);
            }

            Collections.sort(listOfDirectories);
            if(listOfDirectories.isEmpty())
                    label.setText("No Directory Selected");
            else
                label.setText("Selected Directories : " + listOfDirectories.toString());
            revalidate();
        }

    }

    public class RemoveDirectoryAction extends AbstractAction{

        public RemoveDirectoryAction() {
            putValue(Action.NAME, "Remove Disk/Directory");
            putValue(Action.SHORT_DESCRIPTION, "Remove Disk/Directory from the List");
        }

        public void actionPerformed(ActionEvent e) {
            revalidate();
            String list = JOptionPane.showInputDialog(null, "Input names of drives/directories to remove and separe them with coma (\",\"):", "Remove Directory", 1);
            if(list == null || list.isEmpty())
                return;
            String[] directories = list.split(",");
            for(String directory : directories){
                directory = directory.trim();
                if(directory.length() == 1){
                    directory = directory + ":/";
                }
                if(listOfDirectories.contains(directory))
                    listOfDirectories.remove(directory);
                else if(!directory.isEmpty())
                    listOfNonDir.add(directory);
            }
            if(!listOfNonDir.isEmpty()){
                JOptionPane.showMessageDialog(null, listOfNonDir.toString()+" is not selected", "Message", 1);
                listOfNonDir.removeAll(listOfNonDir);
            }

            if(listOfDirectories.isEmpty())
                    label.setText("No Directory Selected");
                else
                    label.setText("Selected Directories : " + listOfDirectories.toString());

            revalidate();
        }

    }

}